package com.yuanjun.product.utils;

import com.yuanjun.product.model.bean.TimeQuantum;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author: ZSC
 * @time: 2020/2/4
 */
public class DateUtil {

    public static Logger logger = LoggerFactory.getLogger(DateUtil.class);

    public static SimpleDateFormat yyyyMM = new SimpleDateFormat("yyyy-MM");

    public static SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyy-MM-dd");

    public static SimpleDateFormat yyyyMMddHHmmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static SimpleDateFormat JYyyyyMMdd = new SimpleDateFormat("yyyyMMddHHmmssSSS");

    public static SimpleDateFormat JYHHmmss = new SimpleDateFormat("HHmmssSSS");

    public static Timestamp getCurTimestamp() {
        return new Timestamp(System.currentTimeMillis());
    }

    public static String getFormatDateForToday() {
        return yyyyMMdd.format(new Date());
    }

    public static Date parseFormatDate(String date) {
        Date parse = null;
        try {
            parse = yyyyMMdd.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    public static Date parseFormatDate(String date, String format) {
        Date parse = null;
        try {
            parse = new SimpleDateFormat(format).parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    public static String getFormatDateForToday(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(5, day);
        return yyyyMMdd.format(calendar.getTime());
    }

    public static Date getDateForWeekDay(int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(5, day);
        return calendar.getTime();
    }

    public static List<Map<String, Object>> timeQuantum(TimeQuantum timeQuantum, String date) {
        return timeQuantum(timeQuantum, parseFormatDate(date));
    }

    public static List<Map<String, Object>> timeQuantum(TimeQuantum timeQuantum, Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        List<Map<String, Object>> dateList = new ArrayList();
        int type = timeQuantum.getType();
        if (7 == type) {
            calendar.setFirstDayOfWeek(2);
            calendar.add(5, calendar.getFirstDayOfWeek() - calendar.get(7));
        } else if (5 == type) {
            calendar.set(5, calendar.getActualMinimum(5));
        } else if (2 == type) {
            calendar.add(2, -calendar.get(2));
        }
        calendar.set(11, calendar.getActualMinimum(11));
        int actualMaximum = calendar.getActualMaximum(type);
        int interval = timeQuantum.getInterval();
        int size = actualMaximum % interval == 0 ? actualMaximum / interval : type == 2 ? actualMaximum + 1 : actualMaximum / interval + 1;
        for (int i = 0; i < size; i++) {
            if (2 == type) {
                calendar.set(5, calendar.getActualMinimum(5));
            }
            if (11 != type) {
                calendar.set(11, calendar.getActualMinimum(11));
            }
            calendar.set(12, calendar.getActualMinimum(12));
            calendar.set(13, calendar.getActualMinimum(13));
            Date startTime = calendar.getTime();
            actualMaximum = (5 == type) || (7 == type) || (6 == type) ? actualMaximum : actualMaximum + 1;

            if ((i + 1) * interval <= actualMaximum) {
                calendar.add(type, interval - 1);
            }
            if (2 == type) {
                int maxDay = calendar.getActualMaximum(5);
                calendar.set(5, maxDay);
            }
            if (11 != type) {
                calendar.set(11, calendar.getActualMaximum(11));
            }
            calendar.set(12, calendar.getActualMaximum(12));
            calendar.set(13, calendar.getActualMaximum(13));
            Date endTime = calendar.getTime();
            calendar.add(type, interval > 1 ? interval - 1 : interval);
            Map<String, Object> element = new HashMap();
            element.put("startTime", startTime);
            element.put("endTime", endTime);
            dateList.add(element);
        }

        return dateList;
    }

    public static String format(Date date, String format) {
        return new SimpleDateFormat(format).format(date);
    }

    // 获取天开始
    public static String getCurDayStart() {
        return yyyyMMddHHmmss.format(getCurDayTime(Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0)));
    }

    public static Date getCurDayTime(Integer hour, Integer minute, Integer second) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(11, hour.intValue());
        calendar.set(12, minute.intValue());
        calendar.set(13, second.intValue());
        return calendar.getTime();
    }

    // 获取天结束
    public static String getCurDayEnd() {
        return yyyyMMddHHmmss.format(getCurDayTime(Integer.valueOf(23), Integer.valueOf(59), Integer.valueOf(59)));
    }

    /**
     * 获取本周开始时间
     *
     * @return
     */
    public static Date getWeekendStart() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取本周结束时间
     *
     * @return
     */
    public static Date getWeekendEnd() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.add(Calendar.DAY_OF_WEEK, 6);
        return calendar.getTime();
    }

    /**
     * 获取上周开始时间
     *
     * @return
     */
    public static Date getBeginDayOfLastWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.WEEK_OF_MONTH, -1);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取上周结束时间
     *
     * @return
     */
    public static Date getEndDayOfLastWeek() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.WEEK_OF_MONTH, -1);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.add(Calendar.DAY_OF_WEEK, 6);
        return calendar.getTime();
    }

    public static Date getMonthStart() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取上个月月初
     *
     * @return
     */
    public static Date getLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取上个月月底
     *
     * @return
     */
    public static Date getEndLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 获取本月月底日期
     *
     * @return
     */
    public static Date getLastDateOfMonth() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        return c.getTime();
    }

    /**
     * 2018年第一天时间
     *
     * @return
     */
    public static Date getDateOfYear() {
        Calendar c = Calendar.getInstance();
        c.clear();
        c.set(Calendar.YEAR, 2018);
        return c.getTime();
    }

    /**
     * 获取上一年最后一刻的时间
     *
     * @return
     */
    public static Date getLastDateOfYear() {
        Calendar c = Calendar.getInstance();
        c.clear();
        c.set(Calendar.YEAR, 2018);
        c.roll(Calendar.DAY_OF_YEAR, -1);
        c.set(Calendar.HOUR_OF_DAY, c.getActualMaximum(Calendar.HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMaximum(Calendar.MINUTE));
        c.set(Calendar.SECOND, c.getActualMaximum(Calendar.SECOND));
        return c.getTime();
    }

    /**
     * @return
     */
    public static int getDayOfMonth() {
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        return day;
    }

    /**
     * 获取上个月由多少天
     *
     * @return
     */
    public static int getDayOfLastMonth() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MONTH, -1);
        int day = calendar.getActualMaximum(Calendar.DATE);
        return day;
    }

    /**
     * 获取上个月的日历
     *
     * @return
     */
    public static List<String> getDayListOfMonth() {
        List<String> list = new ArrayList<>();
        Calendar aCalendar = Calendar.getInstance(Locale.CHINA);
        //年份
        int year = aCalendar.get(Calendar.YEAR);
        //月份
        int month = aCalendar.get(Calendar.MONTH) + 1;
        int day = aCalendar.getActualMaximum(Calendar.DATE);
        for (int i = 1; i <= day; i++) {
            String aDate = String.valueOf(year) + "-" + (month < 10 ? "0" + month : month) + "-" + (i < 10 ? "0" + i : i);
            list.add(aDate);
        }
        return list;
    }

    public static Date getDayStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getLastDayStart(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    public static Date getDayEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static Date getLastDayEnd(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, -1);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static Calendar yesterdayDawn() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, -1);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        return calendar;
    }

    public static Calendar tomorrowDawn() {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        return calendar;
    }

    public static Calendar todayDawn() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
        return calendar;
    }

    public static String OCRDateFormate(String date) {
        return date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8);
    }

    public static String getBirthDayByIDCard(String IDCardNum) {
        return IDCardNum.substring(6, 10) + "-" + IDCardNum.substring(10, 12) + "-" + IDCardNum.substring(12, 14);
    }

    public static int dayForWeek(Date tmpDate) {
        Calendar calendar = Calendar.getInstance();
        int[] weekDays = {7, 1, 2, 3, 4, 5, 6};
        calendar.setTime(tmpDate);
        // 指示一个星期中的某天
        int week = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        if (week < 0) {
            week = 0;
        }
        return weekDays[week];
    }

    public static int getWeekForMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.WEEK_OF_MONTH);
    }


    /**
     * 获取某月月初时间
     * @param month
     * @return
     */
    public static Date getSomeMonthStart(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH,month-1);
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取某月月底时间
     * @param month
     * @return
     */
    public static Date getSomeMonthEndLast(int month) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH,month);
        calendar.set(Calendar.DAY_OF_MONTH, 0);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 判断时间是否为当天
     * @param date
     * @return
     */
    public static boolean isCurTime(Date date){
        String curDate = yyyyMMdd.format(new Date());
        String dateFlag = yyyyMMdd.format(date);
        if (curDate.equals(dateFlag)){
            return true;
        }
        return false;
    }

    /**
     * 将身份证号转为生日date
     */
    public static Date getBirthday(String idCardNum){
        String year = idCardNum.substring(6, 10);
        String month =idCardNum.substring(10, 12);
        String day = idCardNum.substring(12, 14);
        String birthday = year + "-" + month + "-" + day;
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = fmt.parse(birthday);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }

    /**
     * 通过身份证判断当天是否为生日
     */
    public static boolean isBirthday(String idCard){
        if (StringUtils.isBlank(idCard)){
            return false;
        }
        String str = idCard.substring(10, 14);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MMdd");
        String today = simpleDateFormat.format(new Date());
        if (str.equals(today)){
            return true;
        }else {
            return false;
        }
    }

    /**
     * 判断日期是否在一个区间内
     */
    public static boolean flagOfDate(Date beginDate,Date endDate,Date flagDate){
        if (beginDate.compareTo(flagDate)==-1&&endDate.compareTo(flagDate)==1){
            return true;
        }
        return false;
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param date1
     * @param date2
     * @return
     */
    public static int differentDaysByMillisecond(Date date1,Date date2)
    {
//        int days = (int) ((date2.getTime() - date1.getTime()) / (1000*3600*24));
        Calendar ca = Calendar.getInstance();
        ca.setTime(date1);
        int days1 = ca.get(Calendar.DAY_OF_YEAR);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date2);
        int days2 = calendar.get(Calendar.DAY_OF_YEAR);
        int days = days2-days1+1;
        return days;
    }

    public static String getDateFormat(Date date,SimpleDateFormat simpleDateFormat) {
        return simpleDateFormat.format(date);
    }
}
